package com.einmeer.hfbank.service.impl;

import com.einmeer.hfbank.entity.Card;
import com.einmeer.hfbank.entity.Deposit;
import com.einmeer.hfbank.entity.InterestRate;
import com.einmeer.hfbank.entity.User;
import com.einmeer.hfbank.hfconst.CardConst;
import com.einmeer.hfbank.hfconst.UserConst;
import com.einmeer.hfbank.mapper.CardMapper;
import com.einmeer.hfbank.mapper.DepositMapper;
import com.einmeer.hfbank.mapper.InterestRateMapper;
import com.einmeer.hfbank.mapper.UserMapper;
import com.einmeer.hfbank.service.UserService;
import com.einmeer.hfbank.vo.ResultVo;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.List;

/**
 * @author 芊嵛
 * @date 2024/1/11
 */

@Service
@Transactional
public class UserServiceImpl implements UserService {
    @Resource
    private UserMapper userMapper;
    @Resource
    private CardMapper cardMapper;
    @Resource
    private DepositMapper depositMapper;
    @Resource
    private InterestRateMapper interestRateMapper;

    /**
     * 登录
     *
     * @param userPhone
     * @param userPassword
     * @return
     */
    @Override
    public ResultVo login(Long userPhone, String userPassword) {
        // 查手机号是否存在
        Long id = userMapper.selectUserByUserPhone0(userPhone);
        // 查删除标记
        Integer delTag = userMapper.selectUserByUserPhone1(userPhone);
        // 查询操作
        Long lId = userMapper.selectUser(userPhone, userPassword);
        // 电话存在
        if (id != null) {
            if (delTag == 0 && lId != null) {
                // delTag为0,密码正确
                return new ResultVo(UserConst.USEROK, lId, UserConst.USERLOGIN);
            } else if (delTag == 0 && lId == null) {
                // delTag为0,密码错误
                return new ResultVo(UserConst.USERNO, UserConst.USERERROR2);
            } else if (delTag == 1) {
                // delTag为1
                return new ResultVo(UserConst.USERNO, UserConst.USERERROR1);
            } else {
                return new ResultVo(UserConst.USERNO, UserConst.ERROR);
            }
        } else {
            // 电话不存在
            return new ResultVo(UserConst.USERNO, UserConst.USERERROR1);
        }

    }

    /**
     * 注册
     *
     * @param user
     * @return
     */
    @Override
    public ResultVo register(User user) {
        Long id = userMapper.selectUserByUserPhone0(user.getUserPhone());
        Integer delTag = userMapper.selectUserByUserPhone1(user.getUserPhone());
        // 判断电话是否存在
        if (id == null) {
            //删除标记为0
            user.setDelTag(0);
            // 执行插入
            int n = userMapper.insertUser(user);
            if (n == 1) {
                return new ResultVo(UserConst.USEROK, UserConst.REGOK);
            } else {
                return new ResultVo(UserConst.USERNO, UserConst.REGNO);
            }
        } else {
            // 判断删除标记
            if (delTag == 0) {
                //电话存在,并且delTag=0
                return new ResultVo(UserConst.USERNO, UserConst.USEREXIST);
            } else if (delTag == 1) {
                //电话存在,并且delTag=1
                //修改delTag
                int n1 = userMapper.updateDelUser(id, delTag);
                // 修改实名
                int n2 = userMapper.updateUser(id, null, null, null);
                if (n1 == 1 && n2 == 1) {
                    return new ResultVo(UserConst.USEROK, UserConst.REGOK);
                } else {
                    return new ResultVo(UserConst.USERNO, UserConst.REGNO);
                }
            }
        }
        return new ResultVo(UserConst.USERNO, UserConst.REGNO);
    }


    /**
     * 实名认证
     * 性别1男2女
     *
     * @param userId
     * @param userName
     * @param userIDCard
     * @return
     */
    @Override
    public ResultVo identification(Long userId, String userName, String userIDCard) {
        Integer userGender = null;
        // 如果身份证为null
        if (userIDCard != null) {
            if (((int) userIDCard.charAt(16)) % 2 == 0) {
                userGender = 2;
            } else {
                userGender = 1;
            }
        }
        int n = userMapper.updateUser(userId, userName, userIDCard, userGender);
        if (n == 1) {
            return new ResultVo(UserConst.USEROK, UserConst.UPDATEOK);
        }
        return new ResultVo(UserConst.USERNO, UserConst.UPDATENO);
    }

    /**
     * 修改昵称
     *
     * @param userId
     * @param userOName
     * @return
     */
    @Override
    public ResultVo changeUserOName(Long userId, String userOName) {
        int n = userMapper.updateUserOName(userId, userOName);
        if (n == 1) {
            return new ResultVo(UserConst.USEROK, UserConst.UPDATEOK);
        }
        return new ResultVo(UserConst.USERNO, UserConst.UPDATENO);
    }

    /**
     * 修改密码
     *
     * @param userId
     * @param OldUserPassword
     * @param NewUserPassword
     * @return
     */
    @Override
    public ResultVo changeUserPassword(Long userId, String OldUserPassword, String NewUserPassword) {
        int n = userMapper.updateUserPassword(userId, OldUserPassword, NewUserPassword);
        if (n == 1) {
            return new ResultVo(UserConst.USEROK, UserConst.UPDATEOK);
        }
        return new ResultVo(UserConst.USERNO, UserConst.UPDATENO);
    }

    /**
     * 查询用户信息
     *
     * @param userId
     * @return
     */
    @Override
    public ResultVo queryUserInfo(Long userId) {
        User user = userMapper.selectUserInfo(userId);
        if (user == null) {
            return new ResultVo(UserConst.USERNO, UserConst.USERQUERYNO);
        }
        return new ResultVo(UserConst.USERNO, user, UserConst.USERQUERYOK);
    }

    /**
     * 删除
     *
     * @param userId
     * @return
     */
    @Override
    public ResultVo changeDelUser(Long userId) {
        User user = userMapper.selectUserInfo(userId);
        Long phone = user.getUserPhone();
        Integer delTag = userMapper.selectUserByUserPhone1(phone);
        int n = userMapper.updateDelUser(userId, delTag);
        if (n == 1) {
//            删除绑卡
            int m = cardMapper.updateDelUser(userId);
            if (m == 1) {
                return new ResultVo(UserConst.USEROK, UserConst.UPDATEOK);
            } else {
                return new ResultVo(UserConst.USEROK, UserConst.UPDATEOK);
            }
        }
        return new ResultVo(UserConst.USERNO, UserConst.UPDATENO);
    }

    /**
     * 根据id查user and card
     *
     * @param userId
     * @return
     */
    @Override
    public ResultVo queryUserById(Long userId) {
        String userOName = userMapper.selectUserById(userId);
        if (userOName == null) {
            return new ResultVo(UserConst.USERNO, UserConst.USERERROR1);
        }
        User user = new User();
        user.setUserOName(userOName);
        List<Card> list = cardMapper.selectAllCards(userId);
        // 遍历集合是否为空
        if (list.isEmpty()) {
            return new ResultVo(CardConst.CARDNO, CardConst.SELECTNO);
        }
        for (Card temp : list) {
            // 根据卡号获取所有活期记录
            List<Deposit> depositList = depositMapper.selectAllByCardNumber(temp.getCardNumber(), 0);
            // 求这张银行卡活期总金额
            BigDecimal a = new BigDecimal(0);
            String sum = null;
            // 遍历是否存数据了
            if (depositList.isEmpty()) {
                temp.setCardCurrent("0");
            } else {
                InterestRate interestRate = interestRateMapper.selectByType(0);
                // 获取活期利率
                BigDecimal rate = new BigDecimal(interestRate.getIRPercentage());
                // 获取几个月经行更新
                int month = interestRate.getIRMonth();
                // 遍历活期表进行高精度计算
                for (Deposit deposit : depositList) {
                    // 获得时间
                    Timestamp timestamp = deposit.getDepositDate();
                    long oldTime = timestamp.getTime();
                    Timestamp now = new Timestamp(System.currentTimeMillis());
                    long nowTime = now.getTime();
                    // 时间差,相差几个月
                    long afterMonth1 = (nowTime - oldTime) / 1000 / 60 / 60 / 24 / 30;
                    int afterMonth2 = (int) afterMonth1;
                    // 更新过几次
                    int times = deposit.getDepositTimes();
                    // 需要再更新几次
                    int againTimes = afterMonth2 / month;
                    // 获取未更新的depositAmount
                    BigDecimal b = new BigDecimal(deposit.getDepositAmount());
                    // 1+利率
                    BigDecimal c = new BigDecimal(1);
                    rate = rate.add(c);
                    // 得到真实金额
                    int tempAgainTimes = againTimes;
                    while (tempAgainTimes != 0) {
                        b = b.multiply(rate);
                        tempAgainTimes--;
                    }
                    // 更新deposit表,前提数据更新了
                    if (againTimes != 0) {
                        againTimes += times;
                        depositMapper.updateDeposit(deposit.getDepositId(), b.toPlainString(), now, againTimes);
                    }
                    a = a.add(b);
                }
                // 转为字符串
                sum = a.toPlainString();
                temp.setCardCurrent(sum);
                // 把活期存款插入card表中
                cardMapper.updateCardCurrent(temp.getCardNumber(), sum);
            }
        }
        user.setCards(list);
        return new ResultVo(UserConst.USEROK, user, UserConst.USERQUERYOK);
    }

    /**
     * 忘记密码
     *
     * @param userPhone
     * @param userPassword
     * @return
     */
    @Override
    public ResultVo forgetPassword(Long userPhone, String userPassword) {
        // 查询userPhone是否存在
        Long userId = userMapper.selectUserByUserPhone0(userPhone);
        if (userId == null) {
            return new ResultVo(UserConst.USERNO, UserConst.USERERROR1);
        } else {
            // 更新密码
            int n = userMapper.updateForgetPassword(userId, userPassword);
            if (n == 0) {
                return new ResultVo(UserConst.USERNO, UserConst.UPDATENO);
            } else {
                return new ResultVo(UserConst.USEROK, UserConst.UPDATEOK);
            }
        }
    }


}
